/*
 * Copyright (c) 2018 - 2028. www.vtuzx.com Inc. All Rights Reserved
 */
package com.vtuzx.kingdee.xqc_api.service.impl;

import com.vtuzx.core.VtuzxException;
import com.vtuzx.core.bean.dto.VtuzxMap;
import com.vtuzx.core.bean.dto.VtuzxPage;
import com.vtuzx.core.constant.IVtuzxConst;
import com.vtuzx.core.file.excel.VtuzxExcel;
import com.vtuzx.core.file.excel.VtuzxExcelCell;
import com.vtuzx.core.file.excel.VtuzxExcelRow;
import com.vtuzx.core.file.excel.VtuzxExcelSheet;
import com.vtuzx.core.utils.VtuzxUtil;
import com.vtuzx.fast.service.IFastSettingService;
import com.vtuzx.fast.utils.FastUtil;
import com.vtuzx.kingdee.xqc_api.config.XqcConfig;
import com.vtuzx.kingdee.xqc_api.service.IXqcBasicService;
import com.vtuzx.kingdee.xqc_api.service.IXqcInventoryService;
import com.vtuzx.kingdee.xqc_api.service.IXqcStockTakeService;
import com.vtuzx.kingdee.xqc_api.service.IXqcTraceBackService;
import com.vtuzx.kingdee.xqc_core.bean.VtuzxArrayList;
import com.vtuzx.kingdee.xqc_core.bean.xqc.BillMaterial;
import com.vtuzx.kingdee.xqc_core.bean.xqc.BillMaterialBox;
import com.vtuzx.kingdee.xqc_core.constant.BillEvent;
import com.vtuzx.kingdee.xqc_core.constant.BillStatus;
import com.vtuzx.kingdee.xqc_core.constant.BillType;
import com.vtuzx.kingdee.xqc_core.constant.IXqcConst;
import com.vtuzx.kingdee.xqc_core.dao.*;
import com.vtuzx.web.bean.VtuzxDownloadBean;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class XqcTraceBackServiceImpl implements IXqcTraceBackService {

    /** Logger */
    private static final Logger _logger = LoggerFactory.getLogger(XqcTraceBackServiceImpl.class);

    @Autowired
    private TraceabilityCodeDetailDao traceabilityCodeDetailDao;

    @Autowired
    private TraceabilityHistoryDao traceabilityHistoryDao;
    @Autowired
    IFastSettingService settingService;

    @Autowired
    private InventoryDetailDao inventoryDetailDao;

    @Autowired
    private PrdColDao prdColDao;

    @Autowired
    private PrdColDetailDao prdColDetailDao;

    @Autowired
    private InventoryDao inventoryDao;

    @Autowired
    private MaterialDao materialDao;

    @Autowired
    private SupplierDao supplierDao;

    @Autowired
    private CertificateDao certificateDao;

    @Autowired
    private PrdProcessDao prdProcessDao;

    @Autowired
    private XqcConfig config;

    @Autowired
    private TraceBackDataDao traceBackDataDao;

    @Override
    public VtuzxMap traceBackCodeBinkBoxNo(ObjectId userId, String name, Map<String, Object> param) throws VtuzxException {
        String traceBackCode = VtuzxUtil.getString(param, "traceBackCode");

        Document doc = traceabilityCodeDetailDao.findOne(Criteria.where("scanning").is(true).and("scanningUserId").is(userId));

        if (!VtuzxUtil.isEmpty(doc)) {
            throw new VtuzxException("已扫描追溯码,请扫描箱号进行绑定");
        }

        traceabilityCodeDetailDao.updateOne(Criteria.where("traceabilityCode").is(traceBackCode),
                new Document("scanning", true)
                        .append("scanningUserId", userId)
                        .append("scanningUserName", name));


        return null;
    }

    @Override
    public VtuzxMap getTraceBackCodeData(Map<String, Object> param) throws VtuzxException {
        VtuzxMap sysParamMap = settingService.getParameters(new VtuzxMap("keys", new VtuzxArrayList<>("traceabilityCodeUrl")));
        VtuzxMap traceabilityCodeUrlMap = VtuzxUtil.getObject(sysParamMap, "traceabilityCodeUrl");
        if (traceabilityCodeUrlMap == null) {
            throw new VtuzxException(IXqcConst.Msg_E_system);
        }
        String value = VtuzxUtil.getString(traceabilityCodeUrlMap, "value");
        String traceabilityCode = VtuzxUtil.getString(param, "traceabilityCode");
        String traceStr = "";
        if (traceabilityCode.startsWith("Z")) {
            traceStr = traceabilityCode;
        } else {
            traceStr = traceabilityCode.substring(traceabilityCode.indexOf("=") + 1);
        }
        boolean fake = false;
        Document traceabilityCodeDoc = traceabilityCodeDetailDao.findOne(Criteria.where("traceabilityCode").is(value + "?traceabilityCode=" + traceStr));
        if (null != traceabilityCodeDoc){
            fake = VtuzxUtil.getBoolean(traceabilityCodeDoc,"fake");//是否是假数据
        }

        _logger.info(value + "?traceabilityCode=" + traceStr);

        //如果是假数据的话直接从表里查数据,不是的话正常进行
        if(fake){
            VtuzxMap data = new VtuzxMap();
            data.append("batchNo", VtuzxUtil.getString(traceabilityCodeDoc,"batchNo"))
                    .append("materialName",  VtuzxUtil.getString(traceabilityCodeDoc,"materialName"))
                    .append("materialSpec", VtuzxUtil.getString(traceabilityCodeDoc,"materialSpec"))
                    .append("prdStandardNo",  VtuzxUtil.getString(traceabilityCodeDoc,"prdStandardNo"))
                    .append("seaAreaLocationStr", VtuzxUtil.getString(traceabilityCodeDoc,"seaAreaLocationStr"))
                    .append("prdLicence", VtuzxUtil.getString(traceabilityCodeDoc,"prdLicence"))
                    .append("seaAreaLocation", VtuzxUtil.getString(traceabilityCodeDoc,"seaAreaLocation"))
                    .append("inspectionResults", VtuzxUtil.getString(traceabilityCodeDoc,"inspectionResults"))
                    .append("frequency", VtuzxUtil.getString(traceabilityCodeDoc,"frequency"))
                    .append("saleChnnel",VtuzxUtil.getString(traceabilityCodeDoc,"saleChnnel"))
                    .append("lastTime",VtuzxUtil.getString(traceabilityCodeDoc,"lastTime"))
                    .append("issue",VtuzxUtil.getString(traceabilityCodeDoc,"issue"))
                    .append("receive",VtuzxUtil.getString(traceabilityCodeDoc,"receive"))
                    .append("createTime", VtuzxUtil.getObject(traceabilityCodeDoc,"createTime"));


            return data;
        }
        if (VtuzxUtil.isEmpty(traceabilityCodeDoc)) {
            throw new VtuzxException("追溯码不存在");
        }

        int frequencyNum = 1;
        Document hisDoc = traceabilityHistoryDao.findOne(Criteria.where("code").is(traceStr));
        if (!VtuzxUtil.isEmpty(hisDoc)) {
            frequencyNum = VtuzxUtil.getInt(hisDoc, "frequency") + frequencyNum;
        }
        traceabilityCodeDetailDao.updateOne(Criteria.where("traceabilityCode").is(traceabilityCode), new Document("frequency", frequencyNum));

        VtuzxMap data = new VtuzxMap();
        Document prdColDetail = prdColDetailDao.findOne(Criteria.where("traceBack").in(value + "?traceabilityCode=" + traceStr).and("noPrint").is(false));
        if (VtuzxUtil.isEmpty(prdColDetail)) {
            throw new VtuzxException("追溯码未绑定或箱号未打印");
        }
        String materialNo = VtuzxUtil.getString(prdColDetail, "materialNo");
        Document certificateDoc = certificateDao.findOne(Criteria.where("prdSmallType").is(materialNo.substring(0, 6)));
        if (VtuzxUtil.isEmpty(certificateDoc)) {
            certificateDoc = certificateDao.findOne(Criteria.where("prdBigType").is(materialNo.substring(0, 4)));
        }
        String prdStandardNo = "";
        String prdLicence = "";
        String checkResult = "";
        if (!VtuzxUtil.isEmpty(certificateDoc)) {
            prdStandardNo = VtuzxUtil.getString(certificateDoc, "prdStandardNo"); //标准号
            prdLicence = VtuzxUtil.getString(certificateDoc, "prdLicence"); //许可证
            checkResult = VtuzxUtil.getString(certificateDoc, "checkResult"); //检验结果
        }

        String seaAreaLocation = "";
        String seaAreaLocationStr = "";
        Document materialDoc = materialDao.findOne(Criteria.where("fNumber").is(materialNo));
        String materialName = VtuzxUtil.getString(materialDoc, "fName");
        String materialSpec = VtuzxUtil.getString(materialDoc, "fSpecification");
        //查询物料的保质期有的话按照物料的保质期计算
        //没有的话判断物料编码是否是0401开头，0401的话是540天，不是的话默认365天
        Integer shelfCount = VtuzxUtil.getInt(materialDoc,"shelfCount");
        if (shelfCount == 0){//如果当前没有维护保质期
            if(materialNo.startsWith("0401")){
                shelfCount = 540;
            } else {
                shelfCount = 365;
            }

        }
        Document traceBackDoc = traceabilityCodeDetailDao.findOne(Criteria.where("traceabilityCode").is(value + "?traceabilityCode=" + traceStr));
        String saleChnnel = VtuzxUtil.getString(traceBackDoc,"saleChnnel");//销售渠道
        //去除销售渠道前面的字母和尾部信息
        if (saleChnnel.startsWith("bb")){
            Pattern pattern = Pattern.compile("[\\da-zA-Z]");
            Matcher matcher = pattern.matcher(saleChnnel);
            String result = matcher.replaceAll("");//处理前面
            saleChnnel = result.substring(0,result.indexOf('-'));//处理后面
        }
        if (saleChnnel.startsWith("外埠")){
            saleChnnel = saleChnnel.substring(0,4);
        }
        String lastTime = VtuzxUtil.getString(traceBackDoc,"lastTime");//销售时间
        String issue = VtuzxUtil.getString(traceBackDoc,"issue");//发出
        String receive = VtuzxUtil.getString(traceBackDoc,"receive");//接收
        //去除销售渠道前面的字母和尾部信息
        if (receive.startsWith("bb")){
            Pattern pattern = Pattern.compile("[\\da-zA-Z]");
            Matcher matcher = pattern.matcher(receive);
            String result = matcher.replaceAll("");//处理前面
            receive = result.substring(0,result.indexOf('-'));//处理后面
        }
        if (receive.startsWith("外埠")){
            receive = receive.substring(0,4);
        }
        String boxNo = VtuzxUtil.getString(traceBackDoc, "boxNo");
        if (VtuzxUtil.isEmpty(boxNo)) {
            traceBackDoc = prdColDetailDao.findOne(Criteria.where("traceBack").in(value + "?traceabilityCode=" + traceStr).and("noPrint").is(false));
        }
        String boxNo1 = VtuzxUtil.getString(traceBackDoc, "boxNo");

        Document prdColDoc = prdColDetailDao.findOne(Criteria.where("boxNo").is(boxNo1));
        String billNo = VtuzxUtil.getString(prdColDoc, "billNo");
        Document colDoc = prdColDao.findOne(Criteria.where("billNo").is(billNo));
        String supplierBatchNo = "";
        String supplierBatchNoStr = VtuzxUtil.getString(colDoc, "supplierBatchNo");
        Date createTime = VtuzxUtil.getObject(colDoc, "createTime");
        String produceDate = VtuzxUtil.getString(colDoc,"produceDate");
        String shelfDate = "";//保质期至
        if (VtuzxUtil.isEmpty(produceDate)){//如果保质期为空的话
            produceDate = VtuzxUtil.formatYmdHmsF(createTime);

            shelfDate = VtuzxUtil.formatYmd(VtuzxUtil.calcDate(createTime,Calendar.HOUR_OF_DAY,shelfCount));
        } else {
            Date prdDate = VtuzxUtil.parseDate(produceDate,new SimpleDateFormat("yyyy-MM-dd "));
            shelfDate = VtuzxUtil.formatYmdF(VtuzxUtil.calcDate(prdDate,Calendar.DAY_OF_MONTH,shelfCount));
        }
        String batchNo = VtuzxUtil.getString(colDoc, "batchNo");
        //处理bn批次的改变后会影响页面展示的批次信息
        String batchNoUp = batchNo;
        if(batchNo.startsWith("BN")){
            batchNo = batchNo.substring(2,batchNo.length());
        }
        if (materialNo.startsWith("0401")) {
            if (Character.isAlphabetic(batchNo.charAt(0))) {
                supplierBatchNo = batchNo.substring(2, 4);
            } else {
                supplierBatchNo = batchNo.substring(1, 3);
            }
            if (!VtuzxUtil.isEmpty(supplierBatchNoStr)) {
                if (Character.isAlphabetic(supplierBatchNoStr.charAt(0))) { //判断第一位是不是字母
                    supplierBatchNo = supplierBatchNoStr.substring(2, 4);
                } else {
                    supplierBatchNo = supplierBatchNoStr.substring(1, 3);
                }
            }
        } else if (supplierBatchNoStr.startsWith("Y1") || supplierBatchNoStr.startsWith("Y2") || batchNo.startsWith("Y1") || batchNo.startsWith("Y2")) {
            if (VtuzxUtil.isEmpty(supplierBatchNoStr)) {
                if (Character.isAlphabetic(batchNo.charAt(0))) {
                    supplierBatchNo = batchNo.substring(2, 4);
                } else {
                    supplierBatchNo = batchNo.substring(1, 3);
                }
            } else {
                if (Character.isAlphabetic(supplierBatchNoStr.charAt(0))) {
                    supplierBatchNo = supplierBatchNoStr.substring(2, 4);
                } else {
                    supplierBatchNo = supplierBatchNoStr.substring(1, 3);
                }
            }
        } else {
            if (VtuzxUtil.isEmpty(supplierBatchNoStr)) {
                if (Character.isAlphabetic(batchNo.charAt(0))) {//判断开头是否是字母
                    supplierBatchNo = batchNo.substring(1, 3);
                } else {
                    supplierBatchNo = batchNo.substring(0, 2);
                }
            } else {
                if (Character.isAlphabetic(supplierBatchNoStr.charAt(0))) {
                    supplierBatchNo = supplierBatchNoStr.substring(1, 3);
                } else {
                    supplierBatchNo = supplierBatchNoStr.substring(0, 2);
                }
            }
        }
        Document supDoc = supplierDao.findOne(Criteria.where("f_ora_pch").is(supplierBatchNo));
        if (!VtuzxUtil.isEmpty(supDoc)) {
            seaAreaLocation = VtuzxUtil.getString(supDoc, "seaAreaPosition");
            seaAreaLocationStr = VtuzxUtil.getString(supDoc, "seaAreaPositionStr");
        }
        data.append("batchNo", VtuzxUtil.isEmpty(supplierBatchNoStr)? batchNoUp : supplierBatchNoStr)
                .append("materialName", materialName)
                .append("materialSpec", materialSpec)
                .append("prdStandardNo", prdStandardNo)
                .append("seaAreaLocationStr", seaAreaLocationStr)
                .append("prdLicence", prdLicence)
                .append("seaAreaLocation", seaAreaLocation)
                .append("inspectionResults", checkResult)
                .append("frequency", frequencyNum)
                .append("saleChnnel",saleChnnel)
                .append("lastTime",lastTime)
                .append("issue",issue)
                .append("receive",receive)
                .append("shelfDate",shelfDate)
                .append("createTime", produceDate);


        return data;
    }

    @Override
    public void updateTraceBackData(Map<String, Object> param) {
        //TODO 待修改
        List<Map<String, Object>> prdInformation = VtuzxUtil.getObject(param, "prdInformation");
        List<Map<String, Object>> testingCenter = VtuzxUtil.getObject(param, "testingCenter");
        List<Map<String, Object>> enterprise = VtuzxUtil.getObject(param, "enterprise");
        List<Map<String, Object>> product = VtuzxUtil.getObject(param, "product");
        List<Map<String, Object>> news = VtuzxUtil.getObject(param, "news");
        Document prdInformationDoc = traceBackDataDao.findOne(Criteria.where("type").is("prdInformation"));
        if (VtuzxUtil.isEmpty(prdInformationDoc)) {
            traceBackDataDao.insertOne(new Document("data", prdInformation).append("type", "prdInformation"));
        } else {
            traceBackDataDao.updateOne(Criteria.where("type").is("prdInformation"), new Document("data", prdInformation));
        }
        Document newsDoc = traceBackDataDao.findOne(Criteria.where("type").is("news"));
        if (VtuzxUtil.isEmpty(newsDoc)) {
            traceBackDataDao.insertOne(new Document("data", news).append("type", "news"));
        } else {
            traceBackDataDao.updateOne(Criteria.where("type").is("news"), new Document("data", news));
        }
        Document testingCenterDoc = traceBackDataDao.findOne(Criteria.where("type").is("testingCenter"));
        if (VtuzxUtil.isEmpty(testingCenterDoc)) {
            traceBackDataDao.insertOne(new Document("data", testingCenter).append("type", "testingCenter"));
        } else {
            traceBackDataDao.updateOne(Criteria.where("type").is("testingCenter"), new Document("data", testingCenter));
        }
        Document enterpriseDoc = traceBackDataDao.findOne(Criteria.where("type").is("enterprise"));
        if (VtuzxUtil.isEmpty(enterpriseDoc)) {
            traceBackDataDao.insertOne(new Document("data", enterprise).append("type", "enterprise"));
        } else {
            traceBackDataDao.updateOne(Criteria.where("type").is("enterprise"), new Document("data", enterprise));
        }
        Document productDoc = traceBackDataDao.findOne(Criteria.where("type").is("product"));
        if (VtuzxUtil.isEmpty(productDoc)) {
            traceBackDataDao.insertOne(new Document("data", product).append("type", "product"));
        } else {
            traceBackDataDao.updateOne(Criteria.where("type").is("product"), new Document("data", product));
        }
    }

    @Override
    public VtuzxMap getTraceBackData(Map<String, Object> param) throws VtuzxException {
        VtuzxMap sysParamMap = settingService.getParameters(new VtuzxMap("keys", new VtuzxArrayList<>("traceabilityCodeUrl")));
        VtuzxMap traceabilityCodeUrlMap = VtuzxUtil.getObject(sysParamMap, "traceabilityCodeUrl");
        if (traceabilityCodeUrlMap == null) {
            throw new VtuzxException(IXqcConst.Msg_E_system);
        }
        String value = VtuzxUtil.getString(traceabilityCodeUrlMap, "value");
        String traceBack = VtuzxUtil.getString(param, "traceBack");
        List<VtuzxMap> prdProcessList = new ArrayList<>();
        //查询当前追溯码是否是假数据
        String traceStr = "";
        if (traceBack.startsWith("Z")) {
            traceStr = traceBack;
        } else {
            traceStr = traceBack.substring(traceBack.indexOf("=") + 1);
        }
        Document traceabilityCodeDoc = traceabilityCodeDetailDao.findOne(Criteria.where("traceabilityCode").is(value + "?traceabilityCode=" + traceStr));
        boolean fake = false;
        if (null != traceabilityCodeDoc){
            fake = VtuzxUtil.getBoolean(traceabilityCodeDoc,"fake");
        }



        if (!VtuzxUtil.isEmpty(traceBack) && !"undefined".equals(traceBack)) {
            String traceBackNo = value + "?traceabilityCode=" + traceBack;
            Document invDetailDoc = inventoryDetailDao.findOne(Criteria.where("traceBack.traceBackNo").is(traceBackNo));
            if (!VtuzxUtil.isEmpty(invDetailDoc)) {
                String inventoryId = VtuzxUtil.getString(invDetailDoc, "_inventoryId");
                Document invDoc = inventoryDao.findById(inventoryId);
                if (!VtuzxUtil.isEmpty(invDoc)) {
                    String materialNo = VtuzxUtil.getString(invDoc, "materialNo");
                    String prdBigType = materialNo.substring(0, 4);
                    String prdSmallType = materialNo.substring(0, 6);
                    List<String> prdProcessNameList = new ArrayList<>();
                    Iterator<Document> certificateDocItr = certificateDao.findList(Criteria.where("prdBigType").is(prdBigType).and("prdSmallType").is(prdSmallType), null, 0, 0);
                    while (certificateDocItr.hasNext()) {
                        Document certificateDoc = certificateDocItr.next();
                        String prdProcessName = VtuzxUtil.getString(certificateDoc, "prdProcessName");
                        prdProcessNameList.add(prdProcessName);
                    }

                    Iterator<Document> prdProcessItr = prdProcessDao.findList(Criteria.where("prdProcessName").in(prdProcessNameList), null, 0, 0);
                    while (prdProcessItr.hasNext()) {
                        Document prdProcessDoc = prdProcessItr.next();
                        String prdProcessName = VtuzxUtil.getString(prdProcessDoc, "prdProcessName");
                        String content = VtuzxUtil.getString(prdProcessDoc, "content");
                        String pic = VtuzxUtil.getString(prdProcessDoc, "pic");
                        VtuzxMap prdProcessMap = new VtuzxMap("title", prdProcessName).append("content", content).append("url", config.rootUrl() + "prdProcess/" + pic);
                        prdProcessList.add(prdProcessMap);
                    }
                }
            } else {//如果在即时库存没有数据说明是假数据

                String materialNo = VtuzxUtil.getString(traceabilityCodeDoc, "materialNo");
                String prdBigType = materialNo.substring(0, 4);
                String prdSmallType = materialNo.substring(0, 6);
                List<String> prdProcessNameList = new ArrayList<>();
                Iterator<Document> certificateDocItr = certificateDao.findList(Criteria.where("prdBigType").is(prdBigType).and("prdSmallType").is(prdSmallType), null, 0, 0);
                while (certificateDocItr.hasNext()) {
                    Document certificateDoc = certificateDocItr.next();
                    String prdProcessName = VtuzxUtil.getString(certificateDoc, "prdProcessName");
                    prdProcessNameList.add(prdProcessName);
                }

                Iterator<Document> prdProcessItr = prdProcessDao.findList(Criteria.where("prdProcessName").in(prdProcessNameList), null, 0, 0);
                while (prdProcessItr.hasNext()) {
                    Document prdProcessDoc = prdProcessItr.next();
                    String prdProcessName = VtuzxUtil.getString(prdProcessDoc, "prdProcessName");
                    String content = VtuzxUtil.getString(prdProcessDoc, "content");
                    String pic = VtuzxUtil.getString(prdProcessDoc, "pic");
                    VtuzxMap prdProcessMap = new VtuzxMap("title", prdProcessName).append("content", content).append("url", config.rootUrl() + "prdProcess/" + pic);
                    prdProcessList.add(prdProcessMap);
                }
            }
        }

        VtuzxMap data = new VtuzxMap();
        Iterator<Document> dataItr = traceBackDataDao.findList(null, null, 0, 0);
        while (dataItr.hasNext()) {
            Document doc = dataItr.next();
            String type = VtuzxUtil.getString(doc, "type");
            List<Document> dataList = VtuzxUtil.getObject(doc, "data");
            data.append(type, dataList);
        }
        if (!VtuzxUtil.isEmpty(traceBack) && !"undefined".equals(traceBack)) {
            data.append("prdProcess", prdProcessList);
        }
        //图片地址集合
        List<VtuzxMap> reportList = new ArrayList<>();
        //视频信息集合
        List<VtuzxMap> videoList = new ArrayList<>();



        if (!VtuzxUtil.isEmpty(traceBack) && !"undefined".equals(traceBack)) {
            String materialNo = "";
            //如果是假数据直接从表里取物料编码
            if (fake){
                materialNo = VtuzxUtil.getString(traceabilityCodeDoc,"materialNo");
            } else {
                Document prdColDoc = prdColDetailDao.findOne(Criteria.where("traceBack").in(value + "?traceabilityCode=" + traceBack));
                String billNo = VtuzxUtil.getString(prdColDoc, "billNo");
                Document colDoc = prdColDao.findOne(Criteria.where("billNo").is(billNo));
                materialNo = VtuzxUtil.getString(colDoc, "materialNo");
            }


            Document certificateDoc = null;
            Iterator<Document> certificateDocItr = certificateDao.findList(Criteria.where("prdSmallType").is(materialNo.substring(0, 6)),
                    new Document("updateTime",-1),0,1);
            while (certificateDocItr.hasNext()){
                certificateDoc = certificateDocItr.next();
            }
            if (VtuzxUtil.isEmpty(certificateDoc)) {
                Iterator<Document> certificateDocBigItr = certificateDao.findList(Criteria.where("prdBigType").is(materialNo.substring(0, 4)),
                        new Document("updateTime",-1),0,1);
                while (certificateDocBigItr.hasNext()){
                    certificateDoc = certificateDocBigItr.next();
                }
            }


            //查询证书图片信息
//            Document certificateDoc = certificateDao.findOne(Criteria.where("prdSmallType").is(materialNo.substring(0, 6)));
//            if (VtuzxUtil.isEmpty(certificateDoc)) {
//                certificateDoc = certificateDao.findOne(Criteria.where("prdBigType").is(materialNo.substring(0, 4)));
//            }
            if (!VtuzxUtil.isEmpty(certificateDoc)) {
                List<String> pics = VtuzxUtil.getObject(certificateDoc, "pics");
                if (!VtuzxUtil.isEmpty(pics)) {
                    for (String pic: pics) {
                        //判断是图片还是视频,目前视频只允许mp4格式
                        if(pic.endsWith("mp4")){
                            VtuzxMap picMap = new VtuzxMap();
                            picMap.append("url", config.rootUrl() + "certificate/" + pic);
//                            picMap.append("url", "http://zs.xiaoqin.com.cn/xqc_doc/certificate/20240611/axEnoa85.mp4");
                            videoList.add(picMap);
                        } else {
                            VtuzxMap picMap = new VtuzxMap();
                            picMap.append("url", config.rootUrl() + "certificate/" + pic);
//                            picMap.append("url", "http://zs.xiaoqin.com.cn/xqc_doc/" + "certificate/" + pic);
                            reportList.add(picMap);
                        }
                    }
                }
            }
            data.append("report", reportList);
            data.append("video",videoList);
        }
        return data;
    }

    @Override
    public VtuzxDownloadBean downloadTraceBackList(ObjectId userId, Map<String, Object> param) throws Exception {
        List<Map<String, Object>> dataList = VtuzxUtil.getObject(param, "dataList");
        List<String> billNoList = new ArrayList<>();
        for (Map<String, Object> data: dataList) {
            String billNo = VtuzxUtil.getString(data, "billNo");
            billNoList.add(billNo);
        }
        List<Document> codeList = new ArrayList<>();
        Iterator<Document> codeItr = traceabilityCodeDetailDao.findList(Criteria.where("billNo").in(billNoList), null, 0, 0);
        while (codeItr.hasNext()) {
            Document codeDoc = codeItr.next();
            codeList.add(codeDoc);
        }
        String timestamp = new SimpleDateFormat("yyMMddHHmmss").format(new Date());List<VtuzxExcelSheet> sheets = new ArrayList<>();
        VtuzxExcelSheet sheet0 = new VtuzxExcelSheet(0, "追溯码信息列表");
        int col = 0;
        int row = 0;
        VtuzxExcelRow header0 = new VtuzxExcelRow(row++, new VtuzxArrayList<>(
                new VtuzxExcelCell(col++, "追溯码"),
                new VtuzxExcelCell(col++, "二维码"),
                new VtuzxExcelCell(col++, "箱号"),
                new VtuzxExcelCell(col, "rfid")
        ));
        sheet0.addRow(header0);

        for(Document data: codeList) {
            String traceabilityCode = VtuzxUtil.getString(data, "traceabilityCode");
            String traceStr = traceabilityCode.substring(traceabilityCode.indexOf("=") +1);
            String boxNo = VtuzxUtil.getString(data, "boxNo");
            String rfid = VtuzxUtil.getString(data, "rfid");
            col = 0;
            VtuzxExcelRow dataRow = new VtuzxExcelRow(row++, new VtuzxArrayList<>(
                    new VtuzxExcelCell(col++, traceStr),
                    new VtuzxExcelCell(col++, traceabilityCode),
                    new VtuzxExcelCell(col++, boxNo),
                    new VtuzxExcelCell(col, rfid)
            ));
            sheet0.addRow(dataRow);
        }

        sheet0.setColumnWidth(new VtuzxArrayList<>(
                new int[] { 0, 200 },
                new int[] { 1, 1000 },
                new int[] { 2, 250 },
                new int[] { 3, 250 }
        ));
        sheets.add(sheet0);
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        VtuzxExcel.write(stream, sheets);
        return new VtuzxDownloadBean("追溯码信息" + timestamp + ".xlsx", stream);

    }

    @Override
    public VtuzxMap getTraceBackToData(ObjectId userId, Map<String, Object> param) throws VtuzxException {
        String traceBack = VtuzxUtil.getString(param, "traceBack");
        //从系统参数中获取配置好的路径
        VtuzxMap sysParamMap = settingService.getParameters(new VtuzxMap("keys", new VtuzxArrayList<>("traceabilityCodeUrl")));
        VtuzxMap traceabilityCodeUrlMap = VtuzxUtil.getObject(sysParamMap, "traceabilityCodeUrl");
        if (traceabilityCodeUrlMap == null) {
            throw new VtuzxException(IXqcConst.Msg_E_system);
        }
        String value = VtuzxUtil.getString(traceabilityCodeUrlMap, "value");
        //查询追溯码详细中反写的箱号
        Document traceabilityCodeDoc = traceabilityCodeDetailDao.findOne(Criteria.where("traceabilityCode").is(value + "?traceabilityCode=" + traceBack));
        String boxNo = VtuzxUtil.getString(traceabilityCodeDoc, "boxNo");
        //使用箱号去即时库存中获取物料编码
        Document invDetailDoc = inventoryDetailDao.findOne(Criteria.where("boxNo").is(boxNo));
        ObjectId _inventoryId = VtuzxUtil.getObject(invDetailDoc, "_inventoryId");
        List<String> traceBackList = VtuzxUtil.getObject(invDetailDoc, "traceBack");
        if (!traceBackList.contains(traceBack)) {
            throw new VtuzxException("追溯码绑定错误");
        }
        Document invDoc = inventoryDao.findById(_inventoryId);
        String materialNo = VtuzxUtil.getString(invDoc, "materialNo");

        String prdBigType = materialNo.substring(0, 4);
        String prdSmallType = materialNo.substring(0, 6);

        Document certificateDoc = certificateDao.findOne(Criteria.where("prdBigType").is(prdBigType).and("prdSmallType").is(prdSmallType));
        String prdProcessName = VtuzxUtil.getString(certificateDoc, "prdProcessName");

        List<Document> prdProcessList = new ArrayList<>();
        Iterator<Document> prdProcessItr = prdProcessDao.findList(Criteria.where("prdProcessName").is(prdProcessName), null, 0, 0);
        while (prdProcessItr.hasNext()) {
            Document prdProcessDoc = prdProcessItr.next();
            prdProcessList.add(prdProcessDoc);
        }

        VtuzxMap map = new VtuzxMap();
        Iterator<Document> itr = traceBackDataDao.findList(null, null, 0, 0);
        while (itr.hasNext()) {
            Document doc = itr.next();
            String type = VtuzxUtil.getString(doc, "type");
            VtuzxMap data = VtuzxUtil.getObject(doc, "data");
            map.append("type", type);
            map.append("data", data);
            if ("prdInformation".equals(type)) {
                data.append("controlPoint", prdProcessList);
            }
            map.append(VtuzxUtil.getString(doc, "type"), VtuzxUtil.getObject(doc, "data"));
        }

        return map;
    }
}
